package ac.github.oa.api.common.script.action

import ac.github.oa.OriginAttribute
import ac.github.oa.api.common.script.InlineScript
import ac.github.oa.api.common.script.InlineScriptContext
import ac.github.oa.api.common.script.StringScript
import ac.github.oa.internal.core.item.random.RandomPlant
import taboolib.common.platform.function.info
import taboolib.common.platform.function.warning
import taboolib.common.util.asList
import taboolib.common.util.random
import taboolib.common5.Coerce

object ScriptRandom : InlineScript {

    override val id: String
        get() = "random"

    override fun handleScript(argument: String, context: InlineScriptContext): String? {
        val split = argument.split(":")
        if (split.size == 1) {
            return RandomGroup.handleScript(argument, context)
        } else {
            val builder = randoms[split[0]]
            if (builder == null) {
                warning("random build not found for '${split[0]}'")
                return argument
            }
            return builder.handleScript(argument.substring(split[0].length + 1), context)
        }
    }

    val randoms = mutableMapOf(
        "double" to RandomDouble,
        "int" to RandomInt,
        "group" to RandomGroup
    )

    interface IRandom {

        fun handleScript(argument: String, context: InlineScriptContext): String

    }

    object RandomGroup : IRandom {

        override fun handleScript(argument: String, context: InlineScriptContext): String {
            val config = RandomPlant.configs[argument] ?: "not found $argument"
            return when (config) {
                is String -> StringScript.parse(config, context)
                is List<*> -> StringScript.parse(randomList(config.asList()), context)
                else -> "error type ${config::class.java}"
            }
        }

        fun randomList(list: List<String>): String {
            val mutableList = list.toMutableList()
            mutableList.forEachIndexed { index, s ->
                val indexOf = s.indexOf('#')
                // 检索优先级
                if (indexOf == -1) return@forEachIndexed
                if (random(Coerce.toDouble(s.substring(0, indexOf)))) {

                    // 递归
                    return s.substring(indexOf + 1)

                } else {
                    mutableList[index] = ""
                }
            }
            mutableList.removeIf { it.isEmpty() }
            return if (mutableList.isEmpty()) {
                randomList(list)
            } else {
                mutableList.random()
            }
        }

    }

    object RandomInt : IRandom {
        override fun handleScript(argument: String, context: InlineScriptContext): String {
            val ints = argument.split("-").map { Coerce.toInteger(it) }
            return random(ints[0], ints.getOrElse(1) { ints[0] }).toString()
        }

    }

    object RandomDouble : IRandom {
        override fun handleScript(argument: String, context: InlineScriptContext): String {
            val doubles = argument.split("-").map { Coerce.toDouble(it) }
            return OriginAttribute.decimalFormat.format(
                random(doubles[0], doubles.getOrElse(1) { doubles[0] })
            )
        }

    }


}